package com.ruoyi.docdraw.service.impl;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.docdraw.domain.*;
import com.ruoyi.docdraw.domain.subProject.SysSubProjectVo;
import com.ruoyi.docdraw.domain.supplier.AISupplier;
import com.ruoyi.docdraw.domain.supplier.SyncSupplierVo;
import com.ruoyi.docdraw.domain.supplier.SysSupplierVo;
import com.ruoyi.docdraw.domain.vo.*;
import com.ruoyi.docdraw.mapper.SysDocMasterMapper;
import com.ruoyi.docdraw.service.*;
import com.ruoyi.docdraw.util.HttpUtil;
import com.ruoyi.docdraw.vo.*;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysOperLogMapper;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysOperLogService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

@Service
public class SysGDPServiceImpl implements ISysGDPService {


    @Value("${windchill.xl.download-drawing}")
    private String downloadDrawingUrl;

    @Value("${windchill.xl.login-base64}")
    private String windchillToken;

    @Value("${go-fastdfs.upload-url}")
    private String go_fastDFS_upload_url;

    @Value("${go-fastdfs.query-url}")
    private String go_fastDFS_query_url;

//    @Value("${go-fastdfs.out_host_ip}")
//    private String out_host_ip;
//
//    @Value("${go-fastdfs.in_host_ip}")
//    private String in_host_ip;

    @Value("${go-fastdfs.delete-url}")
    private String go_fastDFS_delete_url;

    @Autowired
    ISysDocMasterService sysDocMasterService;

    @Autowired
    SysDocMasterMapper sysDocMasterMapper;

    @Autowired
    ISysDocService sysDocService;

    @Autowired
    ISysDocDrawService sysDocDrawService;

    @Autowired
    ISysDeptService sysDeptService;

//    @Autowired
//    SysDeptMapper sysDeptMapper;
    @Autowired
    SysOperLogMapper sysOperLogMapper;

    @Autowired
    ISysSupplierService sysSupplierService;

    @Autowired
    ISysProjectService sysProjectService;

    @Autowired
    ISysProjectSupplierService sysProjectSupplierService;

    @Autowired
    ISysSubProjectService sysSubProjectService;
    @Autowired
    private SysUserServiceImpl sysUserServiceImpl;

    @Autowired
    private ISysDocdrawSupplierService sysDocdrawSupplierService;

    /**
     * windchill 端推送文档相关信息处理方法
     * @param reqVo
     * @return
     */
    @Override
    public List<AIDrawingRespVo> insertAndUpdate(SyncReqVo reqVo) {
        List<AIDrawingRespVo> vos = new ArrayList<>();
        Long deptId = reqVo.getDeptId();

        Date requestDate = reqVo.getRequestDate();
        // 待更新请求文档Master
        List<DocMasterVo> docMasters = reqVo.getDocMasters();

        List<DocMasterVo> insertList = new ArrayList<>();
        List<DocMasterVo> updateList = new ArrayList<>();
        for (DocMasterVo docMaster : docMasters) {
            SysDocMaster sysDocMaster = new SysDocMaster();
            sysDocMaster.setDocMasterOr(docMaster.getDocMasterOr());
            sysDocMaster.setDeptId(docMaster.getDeptId());
            List<SysDocMaster> sysDocMasters = sysDocMasterService.selectSysDocMasterList(sysDocMaster);
            if(sysDocMasters.isEmpty()){
                insertList.add(docMaster);
            }else {
                SysDocMaster master = sysDocMasters.get(0);
                docMaster.setDocMasterId(master.getDocMasterId());
                updateList.add(docMaster);
            }
        }

        int insert = insertSysDocMasterAndChild(insertList, deptId);

        int update = updateSysDocMasterAndChild(updateList, deptId);

        return vos;
    }




    /**
     * 修改已存在的文档图纸信息
     * @param docMasters
     * @param vos
     */
    @Transactional
    public int updateSysDocMasterAndChild(List<DocMasterVo> docMasters, Long deptId) {
        int count = 0;
        for (DocMasterVo docMaster : docMasters) {
            SysDocMaster master = new SysDocMaster();
            BeanUtils.copyBeanProp(master, docMaster);
            master.setUpdateTime(docMaster.getUpdateTime());
            List<DocVo> docs = docMaster.getDocs();
            // master没有的doc集合

            for (DocVo doc : docs) {
                SysDoc sysDoc = new SysDoc();
                List<DocDrawVo> docDraws = doc.getDocDraws();
                BeanUtils.copyBeanProp(sysDoc, doc);
                sysDoc.setCreateTime(doc.getReleaseTime());
                sysDoc.setUpdateTime(doc.getReleaseTime());
                SysDoc docByDocOr = sysDocService.selectSysDocByDocOr(doc.getDocOr());
                if(ObjectUtils.isEmpty(docByDocOr)){
                    // 表示这个DOCVO 及docdraw都直接插入
                    sysDoc.setCreateTime(doc.getReleaseTime());
                    sysDoc.setUpdateTime(doc.getReleaseTime());
                    sysDoc.setDocMasterId(docMaster.getDocMasterId());
                    sysDocService.insertSysDoc(sysDoc);

                    Long docId = sysDoc.getDocId();
                    List<Long> supplierIds = doc.getSupplierIds();
                    supplierIds.forEach(ids->{
                        SysDocdrawSupplier sysDocdrawSupplier = new SysDocdrawSupplier();
                        sysDocdrawSupplier.setDocId(docId);
                        sysDocdrawSupplier.setSupplierId(ids);
                        sysDocdrawSupplier.setDeptId(deptId);
                        sysDocdrawSupplier.setDocMasterId(master.getDocMasterId());
                        sysDocdrawSupplierService.insertSysDocdrawSupplier(sysDocdrawSupplier);
                    });
                    for (DocDrawVo docDraw : docDraws) {
                        SysDocDraw sysDocDraw = new SysDocDraw();
                        BeanUtils.copyBeanProp(sysDocDraw, docDraw);
                        sysDocDraw.setDocId(docId);
                        sysDocDraw.setCreateTime(docDraw.getUpdateTime());
                        sysDocDraw.setUpdateTime(docDraw.getUpdateTime());
                        Object byteFile = docDraw.getByteFile();
                        byte[] bytes = null;
                        if (byteFile instanceof byte[]) {
                            bytes = (byte[]) byteFile;
                        }else if (byteFile instanceof String){
                            String base64Data = (String) byteFile;
                            bytes = Base64.getDecoder().decode(base64Data);
                        }
                        // 上传到文件服务器
                        String dfsResp = uploadFileToGoFastDFS(bytes, (master.getDeptId()+"/"+docId),sysDocDraw.getDrawName());
                        if(StringUtils.isNotBlank(dfsResp)){
                            String[] param = parseFastDFSResponse(dfsResp);
                            sysDocDraw.setFileMd5(param[0]);
                            sysDocDraw.setDownloadUrl(param[1]+"?name="+sysDocDraw.getDrawName());
                        }
                        sysDocDrawService.insertSysDocDraw(sysDocDraw);
                    }
                }else {
                    // 删除已有的doc 的docdraw
                    Long docId = docByDocOr.getDocId();
                    sysDoc.setDocId(docId);
                    sysDoc.setDocMasterId(docByDocOr.getDocMasterId());
                    SysDocDraw draw = new SysDocDraw();
                    draw.setDocId(docId);
                    List<SysDocDraw> sysDocDraws = sysDocDrawService.selectSysDocDrawList(draw);
                    // 删除go-fastDFS中的文件
                    for (SysDocDraw sysDocDraw : sysDocDraws) {
                        cn.hutool.http.HttpUtil.get(go_fastDFS_delete_url+sysDocDraw.getFileMd5());
                    }
                    sysDocDrawService.deleteSysDocDrawByDocId(sysDoc.getDocId());

                    // 清空数据库docDraw
                    sysDocService.updateSysDoc(sysDoc);

                    sysDocdrawSupplierService.deleteSysDocdrawSupplierByDocId(docId);
                    // 插入新的图纸权限信息
                    // 清空该文档的供应商权限
                    List<Long> supplierIds = doc.getSupplierIds();
                    supplierIds.forEach(ids->{
                        SysDocdrawSupplier sysDocdrawSupplier = new SysDocdrawSupplier();
                        sysDocdrawSupplier.setDocId(docId);
                        sysDocdrawSupplier.setSupplierId(ids);
                        sysDocdrawSupplier.setDeptId(deptId);
                        sysDocdrawSupplier.setDocMasterId(master.getDocMasterId());
                        sysDocdrawSupplierService.insertSysDocdrawSupplier(sysDocdrawSupplier);
                    });
                    for(DocDrawVo docDraw : docDraws){
                        SysDocDraw sysDocDraw = new SysDocDraw();
                        BeanUtils.copyBeanProp(sysDocDraw ,docDraw);
                        sysDocDraw.setDocId(sysDoc.getDocId());
                        sysDocDraw.setCreateTime(docDraw.getUpdateTime());
                        sysDocDraw.setUpdateTime(docDraw.getUpdateTime());

                        Object byteFile = docDraw.getByteFile();
                        byte[] bytes = null;
                        if (byteFile instanceof byte[]) {
                            bytes = (byte[]) byteFile;
                        }else if (byteFile instanceof String){
                            String base64Data = (String) byteFile;
                            bytes = Base64.getDecoder().decode(base64Data);
                        }
                        // 上传到文件服务器
                        String dfsResp = uploadFileToGoFastDFS(bytes, master.getDeptId()+ "/"+sysDoc.getDocId(),sysDocDraw.getDrawName());
                        if(StringUtils.isNotBlank(dfsResp)){
                            String[] param = parseFastDFSResponse(dfsResp);
                            sysDocDraw.setFileMd5(param[0]);
                            sysDocDraw.setDownloadUrl(param[1]+"?name="+sysDocDraw.getDrawName());
                        }
                        sysDocDrawService.insertSysDocDraw(sysDocDraw);
                    }
                }
            }
            sysDocMasterMapper.updateSysDocMaster(master);
        }
        return count;
    }

    /**
     * 插入系统文档文档相关
     * @param docMasters
     * @return
     */
    @Transactional
    public int insertSysDocMasterAndChild(List<DocMasterVo> docMasters, Long deptId){
        int count = 0;
        for (DocMasterVo docMaster : docMasters) {
            SysDocMaster master = new SysDocMaster();
            BeanUtils.copyBeanProp(master,docMaster);
            master.setCreateTime(docMaster.getUpdateTime());
            master.setUpdateTime(docMaster.getUpdateTime());
            sysDocMasterService.insertSysDocMaster(master);
            List<DocVo> docs = docMaster.getDocs();

            for (DocVo doc : docs) {
                SysDoc sysDoc = new SysDoc();
                BeanUtils.copyBeanProp(sysDoc, doc);
                sysDoc.setDocMasterId(master.getDocMasterId());
                sysDoc.setCreateTime(doc.getReleaseTime());
                sysDoc.setUpdateTime(doc.getReleaseTime());
                sysDocService.insertSysDoc(sysDoc);
                // 划分权限给图纸的版本
                Long docId = sysDoc.getDocId();
                List<Long> supplierIds = doc.getSupplierIds();
                supplierIds.forEach(ids->{
                    SysDocdrawSupplier sysDocdrawSupplier = new SysDocdrawSupplier();
                    sysDocdrawSupplier.setDocId(docId);
                    sysDocdrawSupplier.setSupplierId(ids);
                    sysDocdrawSupplier.setDeptId(deptId);
                    sysDocdrawSupplier.setDocMasterId(master.getDocMasterId());
                    sysDocdrawSupplierService.insertSysDocdrawSupplier(sysDocdrawSupplier);
                });
                List<DocDrawVo> docDraws = doc.getDocDraws();
                for (DocDrawVo docDraw : docDraws) {
                    SysDocDraw sysDocDraw = new SysDocDraw();
                    BeanUtils.copyBeanProp(sysDocDraw, docDraw);
                    sysDocDraw.setCreateTime(docDraw.getUpdateTime());
                    sysDocDraw.setUpdateTime(docDraw.getUpdateTime());
                    sysDocDraw.setDocId(sysDoc.getDocId());
                    Object byteFile = docDraw.getByteFile();
                    byte[] bytes = null;
                    if (byteFile instanceof byte[]) {
                        bytes = (byte[]) byteFile;
                    }else if (byteFile instanceof String){
                        String base64Data = (String) byteFile;
                        bytes = Base64.getDecoder().decode(base64Data);
                    }
                    // 上传到文件服务器
                    String dfsResp = uploadFileToGoFastDFS(bytes, master.getDeptId()+ "/"+sysDoc.getDocId(),sysDocDraw.getDrawName());
                    if(StringUtils.isNotBlank(dfsResp)){
                        String[] param = parseFastDFSResponse(dfsResp);
                        sysDocDraw.setFileMd5(param[0]);
                        sysDocDraw.setDownloadUrl(param[1]+"?name="+sysDocDraw.getDrawName());
                    }
                    sysDocDrawService.insertSysDocDraw(sysDocDraw);
                }
            }
        }
        return count;
    }

    /**
     * 将文件发送至go-fastDfs
     * @param bytes
     * @return
     */
    /**
     * 将文件发送至 go-fastDfs
     * @param bytes 要上传的文件的字节数组
     * @return 上传结果的响应字符串
     */
    public String uploadFileToGoFastDFS(byte[] bytes,String path,String filename) {
        // 检查字节数组是否为空
        if (bytes == null || bytes.length == 0) {
            return "";
        }

        // 将字节数组转换为输入流
        InputStream inputStream = new ByteArrayInputStream(bytes);
        // 创建 InputStreamResource 对象
        InputStreamResource isr = new InputStreamResource(inputStream, filename);

        // 声明参数集合
        Map<String, Object> paramMap = new HashMap<>();
        // 文件输入流资源
        paramMap.put("file", isr);
        // 输出格式
        paramMap.put("output", "json");
        // 自定义路径
        paramMap.put("path", path);
        // 场景
        paramMap.put("scene", "");

        // 上传文件
        String post = cn.hutool.http.HttpUtil.post(go_fastDFS_upload_url, paramMap);
//        if (in_host_ip != null && out_host_ip != null) {
//            // 如果配置的是完整字符串
//            post = post.replace(in_host_ip, out_host_ip);
//        }
        StaticLog.info("上传接口返回值{}",post);
        return post;
    }


    /**
     * 解析 go-fastdfs 上传响应，提取 MD5 和 URL 的主路径部分
     * @param responseBody 上传接口返回的 JSON 响应体
     * @return 包含 MD5 和 URL 主路径的数组，索引 0 为 MD5，索引 1 为 URL 主路径
     * @throws IllegalArgumentException 如果响应体格式不正确或缺少关键字段
     */
    public String[] parseFastDFSResponse(String responseBody) {
        if (JSONUtil.isJson(responseBody)) {
            JSONObject jsonObject = JSONUtil.parseObj(responseBody);
            // 提取 MD5 值
            String md5 = jsonObject.getStr("md5");
            if (md5 == null || md5.isEmpty()) {
                throw new IllegalArgumentException("响应中缺少 MD5 字段");
            }

            // 提取原始 URL 并处理
            String fullUrl = jsonObject.getStr("url");
            if (fullUrl == null || fullUrl.isEmpty()) {
                throw new IllegalArgumentException("响应中缺少 URL 字段");
            }

            // 截取 URL 到问号前的部分
            String urlWithoutQuery = getUrlWithoutQuery(fullUrl);

            return new String[]{md5, urlWithoutQuery};
        } else {
            throw new IllegalArgumentException("传入的不是有效的 JSON 字符串");
        }
    }

    /**
     * 从完整 URL 中提取主路径（去除查询参数和锚点）
     * @param fullUrl 完整 URL 字符串
     * @return 主路径部分（例如：http://example.com/path/to/file）
     */
    private static String getUrlWithoutQuery(String fullUrl) {
        int queryIndex = fullUrl.indexOf('?');
        return queryIndex != -1 ? fullUrl.substring(0, queryIndex) : fullUrl;
    }





    /**
     * 文档历史 数据页面处理
     * @param sysDocMaster
     * @return
     */
    @Override
    public List<SysDocRespVo> docMasterListProcessor(SysDocMaster sysDocMaster) {
        List<SysDocRespVo> vos = new ArrayList<>();
        String docName = sysDocMaster.getDocName();
        String docNumber = sysDocMaster.getDocNumber();
        Long docMasterId = sysDocMaster.getDocMasterId();
        List<SysDoc> sysDocList = sysDocMaster.getSysDocList();

        for (SysDoc sysDoc : sysDocList) {
            SysDocRespVo respVo = new SysDocRespVo();
            BeanUtils.copyBeanProp(respVo, sysDoc);
            respVo.setDocName(docName);
            respVo.setDocNumber(docNumber);
            respVo.setDocMasterId(docMasterId);
            vos.add(respVo);
        }

        return vos;
    }



    /**
     * 图纸信息结果处理
     * @param sysDoc
     * @return
     */
    @Override
    public List<SysDocDrawRespVo> docDrawListProcessor(SysDoc sysDoc) {
        Long docMasterId = sysDoc.getDocMasterId();
        SysDocMaster sysDocMaster = sysDocMasterMapper.selectSysDocMasterByDocMasterId(docMasterId);

        List<SysDocDrawRespVo> vos = new ArrayList<>();
        List<SysDocDraw> sysDocDrawList = sysDoc.getSysDocDrawList();

        for (SysDocDraw sysDocDraw : sysDocDrawList) {
            SysDocDrawRespVo respVo = new SysDocDrawRespVo();
            BeanUtils.copyBeanProp(respVo, sysDocMaster);
            BeanUtils.copyBeanProp(respVo, sysDoc);
            BeanUtils.copyBeanProp(respVo, sysDocDraw);
            vos.add(respVo);
        }
        return vos;
    }

    /**
     * 检查文档是否为最新版本
     * @param docOr
     * @return
     */
    @Override
    public CheckDrawVersionVo checkDrawVersionByOr(String docOr, String deptId, SysUser user) {

        long deptIdLong = Long.parseLong(deptId);
        CheckDrawVersionVo vo = new CheckDrawVersionVo();
        String deptName = sysDeptService.selectDeptById(deptIdLong).getDeptName();
        // 1. 查询当前文档（优先判空）
        SysDoc sysDoc = sysDocService.selectSysDocByDocOr(docOr);
        if (sysDoc == null) {
            vo.setMsg("未找到指定文档");
            return vo;
        }
        Long docMasterId = sysDoc.getDocMasterId();

        SysDocMaster sysDocMaster = sysDocMasterService.selectSysDocMasterByDocMasterId(docMasterId);
        if(deptIdLong != sysDocMaster.getDeptId()){
            vo.setMsg("所查文档不属于组织:"+ deptName);
            return vo;
        }

        // 当前用户组织必须和图纸的组织一致
        Long userDeptId = user.getDeptId();
        if(!user.isAdmin()){
            if(deptIdLong != userDeptId){
                vo.setMsg("当前图纸与当前用户不在同一组织!");
                return vo;
            }
        }


        // 2. 获取同主文档的所有版本
        SysDoc selectDoc = new SysDoc();
        selectDoc.setDocMasterId(docMasterId);
        List<SysDoc> sysDocs = sysDocService.selectSysDocList(selectDoc);

        // 3. 如果没有其他版本，则当前即为最新
        if (sysDocs.isEmpty()) {
            vo.setLasted(1L);
            return vo;
        }

        // 4. 定义版本比较逻辑
        Comparator<SysDoc> versionComparator = (doc1, doc2) -> {
            // 优先比较大版本字母（A < B < C）
            int letterCompare = doc1.getVersionIdentifier().compareTo(doc2.getVersionIdentifier());
            if (letterCompare != 0) return letterCompare;
            // 字母相同则比较迭代版本（数字越大越大，2 > 1）
            int i1 = Integer.parseInt(doc1.getIterationIdentifier());
            int i2 = Integer.parseInt(doc2.getIterationIdentifier());
            return Integer.compare(i1, i2); // 升序排列
        };

        // 5. 找到最高版本
        SysDoc maxVersionDoc = sysDocs.stream()
                .max(versionComparator)
                .orElseThrow(() -> new RuntimeException("版本比较异常"));

        // 6. 判断当前文档是否最新
        boolean isLatest =
                sysDoc.getVersionIdentifier().equals(maxVersionDoc.getVersionIdentifier()) &&
                        sysDoc.getIterationIdentifier().equals(maxVersionDoc.getIterationIdentifier());

        vo.setLasted(isLatest ? 1L : 0L);
        vo.setDocId(sysDoc.getDocId());
        vo.setBelongOrgan(deptName);

        vo.setDocName(sysDocMaster.getDocName());
        vo.setDocNumber(sysDocMaster.getDocNumber());
        vo.setCurrentVersion(sysDoc.getVersionIdentifier()+"."+sysDoc.getIterationIdentifier());
        vo.setMaxVersion(maxVersionDoc.getVersionIdentifier()+"."+maxVersionDoc.getIterationIdentifier());
        vo.setMsg("扫描成功");
        return vo;
    }


    /**
     * 当前用户最近五次扫码历史记录
     * @param username
     * @return
     */
    @Override
    public List<AjaxResult> scanHistory(String username) {
        List<AjaxResult> vos = new ArrayList<>();
        List<SysOperLog> sysOperLogs = sysOperLogMapper.selectOperLogListByOperName(username);


        for (SysOperLog operLog : sysOperLogs) {
            String jsonResult = operLog.getJsonResult();
            AjaxResult result = JSONUtil.toBean(jsonResult, AjaxResult.class);
            if (result.isSuccess()) {
                vos.add(result);
            }
        }

        if (vos.size() > 5) {
            vos = vos.subList(0, 5);
        }
        return vos;
    }


    /**
     * 下从windchill中下载图纸
     * @param sysDocDrawId
     * @param response
     * @throws IOException
     */
    /*
    @Override
    public void downloadDraw(Long sysDocDrawId, HttpServletResponse response) throws IOException {

//        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition, Content-Type");

        SysDocDraw sysDocDraw = sysDocDrawService.selectSysDocDrawByDrawId(sysDocDrawId);
        String drawName = sysDocDraw.getDrawName();
        Long docId = sysDocDraw.getDocId();
        SysDoc sysDoc = sysDocService.selectSysDocByDocId(docId);

        GDPDownloadDrawVo drawVo = new GDPDownloadDrawVo(drawName, sysDoc.getDocOr());

        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Basic " + windchillToken);

        try {
            String respJson = HttpUtil.postJSON(downloadDrawingUrl, JSONUtil.parseObj(drawVo), headers);
            System.err.println("Windchill返回的参数为：" + respJson);

            ResponseVo bean = JSONUtil.toBean(respJson, ResponseVo.class);
            if (bean.getCode() == 200) {
                // 根据服务端返回的数据类型处理
                Object data = bean.getData();

                // 1. 如果服务端返回的是字节数组（byte[]）
                if (data instanceof byte[]) {
                    byte[] bytes = (byte[]) data;
                    try (InputStream inputStream = new ByteArrayInputStream(bytes);
                         OutputStream outputStream = response.getOutputStream()) {

                        // 设置响应头触发下载
                        response.setContentType("application/octet-stream");
                        response.setHeader("Content-Disposition",
                                "attachment; filename=\"" + URLEncoder.encode(drawName, "UTF-8") + "\"");

                        // 直接写入字节数组
                        outputStream.write(bytes);
                        outputStream.flush();
                    }

                    // 2. 如果服务端返回的是 Base64 字符串
                } else if (data instanceof String) {
                    String base64Data = (String) data;
                    byte[] bytes = Base64.getDecoder().decode(base64Data);

                    try (InputStream inputStream = new ByteArrayInputStream(bytes);
                         OutputStream outputStream = response.getOutputStream()) {

                        response.setContentType("application/octet-stream");
                        response.setHeader("Content-Disposition",
                                "attachment; filename=\"" + URLEncoder.encode(drawName, "UTF-8") + "\"");

                        outputStream.write(bytes);
                        outputStream.flush();
                    }

                } else {
                    throw new IllegalArgumentException("未知的 data 类型：" + data.getClass());
                }

            } else {
                outResponse(response, respJson);
            }
        } catch (Exception e) {
            e.printStackTrace();
            outResponse(response, JSONUtil.toJsonStr(ResponseVo.error("文件下载失败：" + e.getMessage())));
        }
    }

    */



    @Override
    public AjaxResult downloadDrawStr(Long sysDocDrawId, HttpServletResponse response, SysUser user) throws IOException {
        SysDocDraw sysDocDraw = sysDocDrawService.selectSysDocDrawByDrawId(sysDocDrawId);

        // 1. 验证图纸是否存在
        if (ObjectUtil.isNull(sysDocDraw)) {
            return AjaxResult.error("图纸不存在");
        }

        Long docId = sysDocDraw.getDocId();
        SysDoc sysDoc = sysDocService.selectSysDocByDocId(docId);
        SysDocMaster docMaster = sysDocMasterService.selectSysDocMasterByDocMasterId(sysDoc.getDocMasterId());
        Long deptId = docMaster.getDeptId();

        SysDept sysDept = sysDeptService.selectDeptById(deptId);

        // 只有图纸的对应的文档和下载者是同一组织才能下载
        if (!user.isAdmin()) {
            if(user.getDeptId() != deptId){
//                outResponse(response, JSONUtil.toJsonStr(AjaxResult.error("用户不属于组织："+sysDept.getDeptName())));
                return AjaxResult.error("用户不属于组织："+sysDept.getDeptName());
            }
        }
        String fileName = sysDocDraw.getDrawName();
        String downloadUrl = sysDocDraw.getDownloadUrl();
        return AjaxResult.success("下载成功", downloadUrl);
    }




    /**
     * 下载图纸
     * @param sysDocDrawId
     * @param response
     * @throws IOException
     */
    @Override
    public void downloadDraw(Long sysDocDrawId, HttpServletResponse response, SysUser user) throws IOException {
        SysDocDraw sysDocDraw = sysDocDrawService.selectSysDocDrawByDrawId(sysDocDrawId);

        // 1. 验证图纸是否存在
        if (ObjectUtil.isNull(sysDocDraw)) {
            response.setStatus(HttpStatus.NOT_FOUND.value()); // 明确返回404状态
            outResponse(response, JSONUtil.toJsonStr(AjaxResult.error("图纸不存在")));
            return;
        }

        Long docId = sysDocDraw.getDocId();
        SysDoc sysDoc = sysDocService.selectSysDocByDocId(docId);
        SysDocMaster docMaster = sysDocMasterService.selectSysDocMasterByDocMasterId(sysDoc.getDocMasterId());
        Long deptId = docMaster.getDeptId();

        SysDept sysDept = sysDeptService.selectDeptById(deptId);

        // 只有图纸的对应的文档和下载者是同一组织才能下载
        if (!user.isAdmin()) {
            if(user.getDeptId() != deptId){
                outResponse(response, JSONUtil.toJsonStr(AjaxResult.error("用户不属于组织："+sysDept.getDeptName())));
            }
        }


        String fileName = sysDocDraw.getDrawName();
        String downloadUrl = sysDocDraw.getDownloadUrl();

        try (InputStream fileStream = fetchFileFromInternalServer(downloadUrl)) { // 从内部服务器获取流
            // 2. 设置强制下载的响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition",
                    "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
            // 3. 流复制（避免内存溢出）
            OutputStream os = response.getOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fileStream.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.flush();
        } catch (IOException e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            outResponse(response, JSONUtil.toJsonStr(AjaxResult.error("下载失败：" + e.getMessage())));
        }
    }


    /**
     *  windchill向GDP推送供应商信息
     * @param reqVo
     * @return
     */
    @Transactional
    @Override
    public AjaxResult insertOrUpdateSupplier(SyncSupplierVo reqVo,String name) {

        List<AISupplier> list = reqVo.getSupplierList();
        Long parentDeptId = reqVo.getDeptId();

        // 通过组织id和供应商名称先从SysDept表中搜索 如果有 修改SysDept表和SysSupplier中对象
        // 若没有 则添加租户到SysDept表和SysSupplier中
        for (AISupplier aiSupplier : list) {
            SysSupplier sysSupplier = new SysSupplier();
            // 待新增或修改的供应商组织名称
            String supplierName = aiSupplier.getSupplierName();
            String supplierAbbreviation = aiSupplier.getSupplierAbbreviation();
            String supplierLifeStatus = aiSupplier.getSupplierLifeStatus();
            String supplierSocialCreditCode = aiSupplier.getSupplierSocialCreditCode();
            String supplierRemarks = aiSupplier.getSupplierRemarks();

            // 用于条件插叙是否已存在同父组织下重名的组织对象
            SysDept selectSysDept = new SysDept();
            selectSysDept.setParentId(parentDeptId);
            selectSysDept.setDeptName(supplierName);
            List<SysDept> sysDepts = sysDeptService.selectDeptListByNameAndId(selectSysDept);
            if(sysDepts.isEmpty()){
                // 父组织对象
                SysDept parentDept = sysDeptService.selectDeptById(parentDeptId);
                // 说明是第一次添加

                SysDept deptInsert = insertSupplierDept(aiSupplier, parentDeptId,parentDept,name);
                // 插入SysSupplier表中的 supplierId 值
                Long insertDeptId = deptInsert.getDeptId();
                BeanUtils.copyBeanProp(sysSupplier, aiSupplier);
                sysSupplier.setSupplierId(insertDeptId);
                sysSupplier.setParentDeptId(parentDeptId);
                sysSupplier.setSupplierAbbreviation(supplierAbbreviation);
                sysSupplier.setSupplierLifeStatus(supplierLifeStatus);
                sysSupplier.setSupplierSocialCreditCode(supplierSocialCreditCode);
                sysSupplier.setSupplierRemarks(supplierRemarks);

                sysSupplier.setCreateBy(name);
                sysSupplierService.insertSysSupplier(sysSupplier);
            }else {
                if(sysDepts.size()==1){
                    // 已存在的供应商对象
                    SysDept exDept = sysDepts.get(0);
                    exDept.setDeptName(supplierName);
                    exDept.setUpdateBy(name);
                    exDept.setUpdateTime(DateUtils.getNowDate());
                    sysDeptService.updateDept(exDept);
                    // 修改SysSupplier 对象
                    BeanUtils.copyBeanProp(sysSupplier, aiSupplier);
                    sysSupplier.setSupplierId(exDept.getDeptId());
                    sysSupplier.setParentDeptId(parentDeptId);
                    sysSupplier.setSupplierAbbreviation(supplierAbbreviation);
                    sysSupplier.setSupplierLifeStatus(supplierLifeStatus);
                    sysSupplier.setSupplierSocialCreditCode(supplierSocialCreditCode);
                    sysSupplier.setSupplierRemarks(supplierRemarks);
                    sysSupplier.setUpdateBy(name);
                    sysSupplierService.updateSysSupplier(sysSupplier);
                }else {
                    return AjaxResult.error("查询到父组织编号："+parentDeptId+"下多个重名组织，请检查数据："+supplierName);
                }
            }
        }
        return AjaxResult.success("同步成功");
    }






    /**
     *  windchill向GDP推送删除供应商信息
     * @param reqVo
     * @return
     */
    @Override
    @Transactional
    public AjaxResult deleteSupplierFromPTC(SyncSupplierVo reqVo) {
        Long deptId = reqVo.getDeptId();
        List<AISupplier> list = reqVo.getSupplierList();
        for (AISupplier aiSupplier : list) {
            String supplierName = aiSupplier.getSupplierName();
            SysDept sysDept = new SysDept();
            sysDept.setDeptName(supplierName);
            sysDept.setParentId(deptId);
            List<SysDept> sysDepts = sysDeptService.selectDeptListByNameAndId(sysDept);
            if(!sysDepts.isEmpty()){
                for (SysDept dept : sysDepts) {
                    sysDeptService.deleteDeptById(dept.getDeptId());
                }
            }

        }
        return AjaxResult.success("删除成功");
    }

    /**
     * 根据当前登录用户的 组织 获取向对应的项目集合
     * @param sysProject
     * @param user
     * @return
     */
    @Override
    public List<SysProject> getProject(SysProject sysProject, SysUser user) {
        if (user.isAdmin()) {
            return sysProjectService.selectSysProjectList(sysProject);
        }
        Long deptId = user.getDeptId();
        if(sysSupplierService.checkUserIsSupplier(user)){
            // 说明当前访问的用户是 租户
            SysProjectSupplier sysProjectSupplier = new SysProjectSupplier();
            sysProjectSupplier.setProjectSupplierId(deptId);
            List<SysProjectSupplier> sysProjectSuppliers = sysProjectSupplierService.selectSysProjectSupplierList(sysProjectSupplier);
            List<Long> projectIds = new ArrayList<>();
            for (SysProjectSupplier projectSupplier : sysProjectSuppliers) {
                projectIds.add(projectSupplier.getProjectId());
            }
            // 在这里执行查询供应商所在项目
            return sysProjectService.supplierSelectProjectList(sysProject, projectIds);
        }else {
            // 说明当前用户属于 供应商
            sysProject.setProjectDeptId(deptId);
            return sysProjectService.selectSysProjectList(sysProject);
        }
    }


    /**
     * 根据当前登录用户获取项目子项目信息
     * @param sysSubProject
     * @param user
     * @return
     */
    @Override
    public List<SysSubProject> getSubProject(SysSubProject sysSubProject, SysUser user) {
        if (user.isAdmin()) {
            return sysSubProjectService.selectSysSubProjectList(sysSubProject);
        }
        Long deptId = user.getDeptId();
        if(sysSupplierService.checkUserIsSupplier(user)){
            // 供应商查看
            sysSubProject.setSubProjectSupplierId(deptId);
            return sysSubProjectService.selectSysSubProjectList(sysSubProject);
        }else {
            // 组织用户查看
            // 不确定是否精确到组织的项目经理
            return sysSubProjectService.selectSysSubProjectList(sysSubProject);
        }
    }


    /**
     * 将sysSubProject 对象转换成SysSubProjectVo
     * @param subProject
     * @return
     */
    @Override
    public SysSubProjectVo getSysSubProjectVo(SysSubProject subProject) {
        SysSubProjectVo vo = new SysSubProjectVo();
        BeanUtils.copyBeanProp(vo, subProject);
        Long projectId = subProject.getProjectId();
        SysProject sysProject = sysProjectService.selectSysProjectByProjectId(projectId);
        vo.setProjectName(sysProject.getProjectName());

        Long projectLeaderId = sysProject.getProjectLeaderId();
        if(ObjectUtil.isNotNull(projectLeaderId)){
            SysUser projectLeader = sysUserServiceImpl.selectUserById(projectLeaderId);
            vo.setProjectLeaderName(projectLeader.getUserName());
            vo.setProjectLeaderNickName(projectLeader.getNickName());
        }

        Long projectDeptId = sysProject.getProjectDeptId();

        SysDept sysDept = sysDeptService.selectDeptById(projectDeptId);
        vo.setDeptName(sysDept.getDeptName());

        Long subProjectSupplierId = subProject.getSubProjectSupplierId();

        if(ObjectUtil.isNotNull(subProjectSupplierId)){
            SysSupplierVo vo1 = sysSupplierService.selectSysSupplierBySupplierId(subProjectSupplierId);
            vo.setSupplierName(vo1.getSupplierName());
            vo.setSupplierAbbreviation(vo1.getSupplierAbbreviation());
        }

        Long subProjectSupplierLeaderId = subProject.getSubProjectSupplierLeaderId();
        if(ObjectUtil.isNotNull(subProjectSupplierLeaderId)){
            SysUser supplierLeader = sysUserServiceImpl.selectUserById(subProjectSupplierLeaderId);
            vo.setSupplierLeaderName(supplierLeader.getUserName());
            vo.setSupplierLeaderNickName(supplierLeader.getNickName());
        }
        return vo;
    }


    /**
     * 暂停所有子项目
     * @param projectId
     * @return
     */
    @Override
    @Transactional
    public int pauseSubProject(Long projectId) {
        SysSubProject sysSubProject = new SysSubProject();
        sysSubProject.setProjectId(projectId);
        List<SysSubProject> sysSubProjects = sysSubProjectService.selectSysSubProjectList(sysSubProject);

        for (SysSubProject subProject : sysSubProjects) {
            subProject.setStatus(UserConstants.USER_DISABLE);
            sysSubProjectService.updateSysSubProject(subProject);
        }
        return 0;
    }


    /**
     * 创建SysSupplier对象前先要创建SysDept对象
     * @param aiSupplier
     * @param parentDeptId
     * @param parentDept
     * @param name
     * @return
     */
    public SysDept insertSupplierDept(AISupplier aiSupplier,Long parentDeptId,SysDept parentDept,String name){
        String supplierName = aiSupplier.getSupplierName();
        SysDept deptInsert= new SysDept();
        deptInsert.setDeptName(supplierName);
        deptInsert.setParentId(parentDeptId);
        deptInsert.setAncestors(parentDept.getAncestors()+","+parentDeptId);
        deptInsert.setOrderNum(0);
        deptInsert.setCreateBy(name);
        deptInsert.setCreateTime(DateUtils.getNowDate());
        sysDeptService.insertDept(deptInsert);

        return deptInsert;
    }





    // 从内部服务器获取文件流（示例）
    private InputStream fetchFileFromInternalServer(String url) throws IOException {
        // 使用HttpClient、URLConnection或其他工具获取流
        URL fileUrl = new URL(url);
        return fileUrl.openStream(); // 简单示例，实际需处理认证和异常
    }



    public void outResponse(HttpServletResponse response, String json) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); // 关键！
        response.getWriter().write(json);
    }


}
